/***************************************************************************
 *   KShootout - online shootout card game.                                *
 *   Copyright (C) 2008, 2009  MacJariel                                   *
 *                                                                         *
 *   KShootout is free software: you can redistribute it and/or modify     *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation, either version 3 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   KShootout is distributed in the hope that it will be useful,          *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with KShootout.  If not, see <http://www.gnu.org/licenses/>.    *
 ***************************************************************************/
#ifndef CARDWIDGET_H
#define CARDWIDGET_H

#include "gametypes.h"
#include "clienttypes.h"
#include <QLabel>

namespace client
{
    class GameActionMgr;

    /**
     * The CardWidget class represents a visual element that displays the face
     * (or back) of a card.
     * @author MacJariel <MacJariel (at) gmail.com>
     */
    class CardWidget: public QLabel
    {
        Q_OBJECT;
    public:
        /// Constructs an empty card widget.
        /// This constructor is provided to allow using CardWidget in Qt Desinger.
        /// You should always use another constructor in code.
        CardWidget(QWidget* parent);

        /// Constructs an unrevealed card widget of type cardType and automatically
        /// sets the pointer to gameActionMgr.
        CardWidget(QWidget* parent, GameActionMgr* gameActionMgr, CardType cardType);

        /// Destroys the card widget.
        ~CardWidget();

        /// Returns reference to card data.
        const CardData& rCardData() const;

        /// Returns the pocket type in which the card is.
        PocketType pocketType() const;

        /// Returns the id of current owner of the card.
        PlayerId ownerId() const;

        /// Returns the CardSizeRole of the card.
        CardSizeRole cardSizeRole() const;

        /// Returns whether the card has highlight.
        bool hasHighlight() const;

        /// Returns the middle point of the card.
        QPoint middlePoint() const;

        /// Resets the card to initial empty state.
        void clear();

        /// Sets the pointer to GameActionMgr, so CardWidget can delegate mouse clicks.
        void setGameActionMgr(GameActionMgr*);

        /// Sets CardData according to newCardData. You must call
        /// updatePixmap() to make changes visible.
        void setCardData(const CardData& cardData);

        /// Sets the pocket type in which the card is.
        void setPocketType(const PocketType&);

        /// Sets the id of current owner of the card.
        void setOwnerId(PlayerId ownerId);

        /// Sets the CardSizeRole of the card. You must call
        /// updateSize() or updatePixmap() to make changes visible.
        void setCardSizeRole(CardSizeRole cardSizeRole);

        /// Sets whether the card has highlight.
        void setHighlight(bool highlight);

        /// Unreveals the card, so now it will show back side. You must call
        /// updatePixmap() to make changes visible.
        void unrevealCard();

        /// Sets the card widget to be role card that will
        /// show given role. If no playerRole is supplied,
        /// unknown role card will be set. You must call
        /// updatePixmap() to make changes visible.
        void setPlayerRoleCard(PlayerRole playerRole = ROLE_UNKNOWN);

        /// Sets the card widget to be character card that will
        /// show given character. If no character is supplied,
        /// unknown character card will be set. You must call
        /// updatePixmap() to make changes visible.
        void setCharacterCard(const QString& character = QString());

        /// Loads new pixmap according to current CardData and updates card size,
        /// according to current cardSizeRole and CardWidgetSizeMgr.
        void updatePixmap();

    public slots:
        /// Updates card size according to current cardSizeRole and CardWidgetSizeMgr.
        void updateSize();

    protected:
        /// Handles mouse clicks and if GameActionMgr is set, delegates them to it.
        virtual void mousePressEvent(QMouseEvent* event);

    private:
        /// Draws card highlight, if set.
        virtual void paintEvent(QPaintEvent* event);

        CardData* const         mp_cardData;
        PocketType              m_pocketType;
        PlayerId                m_ownerId;
        CardSizeRole            m_cardSizeRole;
        bool                    m_hasHighlight;
        GameActionMgr*          mp_gameActionMgr;
    };

    inline const CardData& CardWidget::rCardData() const
    {
        return *mp_cardData;
    }

    inline PocketType CardWidget::pocketType() const
    {
        return m_pocketType;
    }

    inline PlayerId CardWidget::ownerId() const
    {
        return m_ownerId;
    }

    inline CardSizeRole CardWidget::cardSizeRole() const
    {
        return m_cardSizeRole;
    }

    inline bool CardWidget::hasHighlight() const
    {
        return m_hasHighlight;
    }

    inline QPoint CardWidget::middlePoint() const
    {
        return QPoint(size().width() / 2, size().height() / 2);
    }
}

#endif
